package ink.xiaobaibai.controller.monthly;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import ink.xiaobaibai.annotation.InsidePublicResources;
import ink.xiaobaibai.autoConfig.roleResources.ResourcesRoleMapping;
import ink.xiaobaibai.bo.BindOneMonthlyOrder;
import ink.xiaobaibai.bo.SelectMonOrderBo;
import ink.xiaobaibai.common.MyRole;
import ink.xiaobaibai.common.PageInfo;
import ink.xiaobaibai.common.RoleEvents;
import ink.xiaobaibai.common.ServiceResult;
import ink.xiaobaibai.entity.*;
import ink.xiaobaibai.enumOxy.MonthlyDeviceStatus;
import ink.xiaobaibai.enumOxy.MonthlyfeeOrderStatus;
import ink.xiaobaibai.multipleClick.ForbidMultipleClick;
import ink.xiaobaibai.response.ResponseFormat;
import ink.xiaobaibai.service.*;
import ink.xiaobaibai.service.monthly.IOrderProcedureService;
import ink.xiaobaibai.serviceOxy.ISmsService;
import ink.xiaobaibai.units.MySecurity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Set;

/**
 * @description: 月费控制层
 * @author: 小白白
 * @create: 2021-05-29
 **/

@RequestMapping("/monthly")
@RestController
@Api(tags = "月费流程接口+订单接口")
@CrossOrigin
@InsidePublicResources
public class MonthlyController {

    @Autowired
    private IMonthlyfeeOrderService orderService;

    @Autowired
    private IOrderProcedureService orderProcedureService;

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private IMonthlyfeeDepositService depositService;

    @Autowired
    private ILogisticsService logisticsService;

    @Autowired
    private IMonthlyTimedTaskService timedTaskService;

    @Autowired
    private IMonthlyUserDeviceService userDeviceService;

    @Autowired
    private IMonthlyfeeDeviceService deviceService;

    @Autowired
    private ISmsService smsService;

    /**
     * 业务员对应的月费订单
     * 订单id+用户id+机器id+机器码+订单状态
     */
    @PostMapping("/list")
    @ApiOperation("查看订单")
    public ResponseFormat getOrderList(@RequestBody SelectMonOrderBo selectMonOrderBo) {
        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();
        if (!roles.contains(MyRole.POWER_MONTHLY)) {
            RoleEvents roleEvents = new RoleEvents(role);
            roleEvents
                    .distributor(() -> selectMonOrderBo.setAdminUserId(userId))
                    .agent(() -> selectMonOrderBo.setDepId(this.adminUserService.getDepId(userId)))
                    .admin(() -> {
                    })
                    .execute();
        }
        PageInfo<MonthlyfeeOrder> page = this.orderService.getOrderList(selectMonOrderBo);
        return ResponseFormat.success(page);
    }

    @GetMapping("/listByClientId")
    @ApiOperation("根据用户Id查看订单")
    public ResponseFormat getListByClientId(@RequestParam("clientId") Integer clientId,
                                            @RequestParam("pageNum") Integer pageNum,
                                            @RequestParam("pageSize") Integer pageSize) {
        IPage<MonthlyfeeOrder> page = new Page<>(pageNum, pageSize);
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("user_id", clientId);
        IPage<MonthlyfeeOrder> result = this.orderService.page(page, q1);
        return ResponseFormat.success(result);
    }

    /**
     * 包月订单详细
     */
    @GetMapping("/item")
    @ApiOperation("包月订单详细")
    public ResponseFormat getOrderItemById(@RequestParam("orderId") String orderId) {
        String role = MySecurity.getRole();
        Set<String> roles = MySecurity.getRoles();
        Integer userId = MySecurity.getUserId();
        MonthlyfeeOrder order = this.orderService.getById(orderId);
        if (!roles.contains(MyRole.POWER_MONTHLY)) {
            if (role.equals(MyRole.DISTRIBUTOR) && !userId.equals(order.getAdminUserId())) {
                return ResponseFormat.fail("无权查看他人订单详细");
            }
        }
        JSONObject jsonObject = new JSONObject();

        // 再加一个其对应的押金
        if (order.getDepositId() != null) {
            QueryWrapper<MonthlyfeeDeposit> q1 = new QueryWrapper<>();
            q1.eq("order_id", order.getDepositId());
            MonthlyfeeDeposit deposit = this.depositService.getOne(q1);
            jsonObject.put("deposit", deposit);
        }

        // 再加一个物流信息
        Logistics logistics = this.logisticsService.getById(order.getLogisticsId());
        jsonObject.put("logistics", logistics);
        jsonObject.put("order", order);
        // 再加其对应的时间段
        QueryWrapper<MonthlyTimedTask> q2 = new QueryWrapper<>();
        q2.eq("device_id", order.getDeviceId());
        MonthlyTimedTask timedTask = this.timedTaskService.getOne(q2);
        jsonObject.put("timedTask", timedTask);
        return ResponseFormat.success(jsonObject);
    }

    /**
     * 业务员为自己的订单 绑定机器id 和 物流信息
     * 然后新添加记录到 用户-机器映射表
     */
    @PostMapping("/bindOneAdd")
    @ApiOperation("业务员为订单绑定信息")
    public ResponseFormat bindOneAdd(@RequestBody @Validated BindOneMonthlyOrder bindOneMonthlyOrder) {
        Integer deviceId = bindOneMonthlyOrder.getDeviceId();
        QueryWrapper<MonthlyUserDevice> q1 = new QueryWrapper<>();
        q1.eq("device_id", deviceId);
        if (this.userDeviceService.count(q1) != 0) {
            return ResponseFormat.fail("当前机器已经被了客户,不可重复绑定");
        }
        ServiceResult serviceResult = this.orderProcedureService.bindOneAdd(bindOneMonthlyOrder);
        return serviceResult.isOk() ? ResponseFormat.success() : ResponseFormat.fail(serviceResult.toString());
    }

    /**
     * 业务员修改绑定信息
     */
    @PostMapping("/bindOneUpdate")
    @ApiOperation("业务员修改订单绑定信息")
    public ResponseFormat bindOneUpdate(@RequestBody @Validated BindOneMonthlyOrder bindOneMonthlyOrder) {
        ServiceResult serviceResult = this.orderProcedureService.binOneUpdate(bindOneMonthlyOrder);
        return serviceResult.isOk() ? ResponseFormat.success() : ResponseFormat.fail(serviceResult.toString());
    }

    /**
     * 业务员修改客户的物流信息
     */
    @GetMapping("/updateClientInfo")
    @ApiOperation("业务员修改客户的物流信息")
    public ResponseFormat updateClientInfo(@RequestParam("logisticsId") Integer logisticsId,
                                           @RequestParam("name") String name,
                                           @RequestParam("phone") String phone,
                                           @RequestParam("address") String address) {
        QueryWrapper<Logistics> q0 = new QueryWrapper<>();
        q0.select("monthly_order_id");
        q0.eq("id", logisticsId);
        Logistics logistics = this.logisticsService.getOne(q0);
        if (logistics == null) {
            return ResponseFormat.fail("物流信息不存在");
        }
        Integer userId = MySecurity.getUserId();
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("order_id", logistics.getMonthlyOrderId());
        q1.eq("admin_user_id", userId);
        q1.last(" limit 1");
        if (!MySecurity.isPower(MyRole.POWER_MONTHLY) && this.orderService.count(q1) == 0) {
            return ResponseFormat.fail("不可操作他人订单");
        }
        UpdateWrapper<Logistics> u1 = new UpdateWrapper<>();
        u1.set("name", name);
        u1.set("phone", phone);
        u1.set("address", address);
        u1.eq("id", logistics);
        this.logisticsService.update(u1);
        return ResponseFormat.success();
    }

    /**
     * 经理获取审核信息列表
     * 经理以上可读
     */
    @GetMapping("/bindOneList")
    @ApiOperation("经理获取审核信息")
    public ResponseFormat getBindOneList() {
        if (!MyRole.AGENT.equals(MySecurity.getRole())) {
            return ResponseFormat.fail("仅经理可操作");
        }
        Integer userId = MySecurity.getUserId();
        //获取部门id
        Integer depId = this.adminUserService.getDepId(userId);
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("admin_dep_id", depId);
        q1.eq("status", MonthlyfeeOrderStatus.AGENT.getStatus());
        return ResponseFormat.success(this.orderService.list(q1));
    }

    /**
     * 经理通过审核
     */
    @PostMapping("/binTwo")
    @ApiOperation("binTwo 经理通过审核")
    public ResponseFormat binTwo(@RequestBody String orderId) {
        if (!MySecurity.getRole().equals(MyRole.AGENT)) {
            return ResponseFormat.fail("仅可经理审核");
        }
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("order_id", orderId);
        MonthlyfeeOrder order = this.orderService.getOne(q1);
        Integer adminDepId = order.getAdminDepId();
        Integer depId = this.adminUserService.getDepId(MySecurity.getUserId());
        if (!adminDepId.equals(depId)) {
            return ResponseFormat.fail("不可审核其他部门");
        }
        if (!order.getStatus().equals(MonthlyfeeOrderStatus.AGENT.getStatus())) {
            return ResponseFormat.fail("当前状态为:" + order.getStatus() + ",不可审核");
        }
        //审核通过
        UpdateWrapper<MonthlyfeeOrder> u1 = new UpdateWrapper<>();
        u1.set("status", MonthlyfeeOrderStatus.ADMIN.getStatus());
        u1.eq("order_id", orderId);
        //改为管理员状态
        this.orderService.update(u1);
        this.smsService.oaSms(1, "月费机器审核");
        return ResponseFormat.success();
    }

    /**
     * 管理员获取审核列表
     */
    @GetMapping("/bindTwoList")
    @ApiOperation("管理员获取审核信息")
    @ResourcesRoleMapping(resourceName = "管理获取审核集合", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_MONTHLY})
    public ResponseFormat getBindTwoList() {
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("status", MonthlyfeeOrderStatus.ADMIN.getStatus());
        return ResponseFormat.success(this.orderService.list(q1));
    }

    /**
     * 管理员审核通过
     * 修改用户机器状态+订单状态+并且此时开始记载7天后自动激活
     */
    @PostMapping("/binThree")
    @ApiOperation("管理员审核通过")
    @ForbidMultipleClick(key = "#orderId")
    @ResourcesRoleMapping(resourceName = "管理获取审核集合", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_MONTHLY})
    public ResponseFormat binThree(@RequestBody String orderId) {
        QueryWrapper<MonthlyfeeOrder> q1 = new QueryWrapper<>();
        q1.eq("status", MonthlyfeeOrderStatus.ADMIN.getStatus());
        q1.eq("order_id", orderId);
        if (this.orderService.count(q1) == 0) {
            return ResponseFormat.fail("请勿重复审核通过");
        }
        this.orderProcedureService.binThree(orderId);
        return ResponseFormat.success();
    }

    /**
     * 管理员取消当前月费订单(直接将当前订单变为取消状态)
     */
    @PostMapping("/cancel")
    @ApiOperation("取消当前订单 || 如果这台订单已经被绑定机器,那么它的机器会被取回")
    @ResourcesRoleMapping(resourceName = "管理获取审核集合", includeRoleNames = {MyRole.ADMIN, MyRole.POWER_MONTHLY})
    public ResponseFormat cancelOrder(@RequestBody String orderId) {
        MonthlyfeeOrder order = this.orderService.getById(orderId);
        // 如果当前机器已经配置了,那么就给他取消配置
        Integer userId = order.getUserId();
        Integer deviceId = order.getDeviceId();
        if (deviceId != null) {
            // 已经给他配置上了机器,那么就取回这台机器
            QueryWrapper<MonthlyUserDevice> q1 = new QueryWrapper<>();
            q1.eq("user_id", userId);
            q1.eq("device_id", deviceId);
            this.userDeviceService.remove(q1);
            // 机器状态改为空闲中
            UpdateWrapper<MonthlyfeeDevice> u2 = new UpdateWrapper<>();
            u2.set("status", MonthlyDeviceStatus.FREE.getStatus());
            u2.eq("id", deviceId);
            this.deviceService.update(u2);
        }
        order.setStatus(MonthlyfeeOrderStatus.CANCEL.getStatus());
        this.orderService.updateById(order);
        return ResponseFormat.success();
    }


}
